// utils/ocr.js
// OCR识别工具类

class OCRService {
  constructor() {
    // 这里可以配置不同的OCR服务提供商
    this.providers = {
      baidu: {
        apiUrl: 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic',
        apiKey: 'YOUR_BAIDU_API_KEY',
        secretKey: 'YOUR_BAIDU_SECRET_KEY'
      },
      tencent: {
        apiUrl: 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr',
        appId: 'YOUR_TENCENT_APP_ID',
        appKey: 'YOUR_TENCENT_APP_KEY'
      },
      huawei: {
        apiUrl: 'https://ocr.cn-north-4.myhuaweicloud.com/v2.0/ocr/general-text',
        accessKeyId: 'M83S8VCVHYI3FJ9NJXMM',
        secretAccessKey: 'biUgKaKs18aAzQY1aH3JykGh9RNA3rIl0HcF38ky',
        region: 'cn-north-4',
        projectId: 'cn-north-4'
      }
    }
  }

  // 百度OCR识别
  async baiduOCR(imageBase64) {
    try {
      // 获取access token
      const tokenResponse = await wx.request({
        url: `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${this.providers.baidu.apiKey}&client_secret=${this.providers.baidu.secretKey}`,
        method: 'POST'
      })

      const accessToken = tokenResponse.data.access_token

      // 调用OCR API
      const ocrResponse = await wx.request({
        url: `${this.providers.baidu.apiUrl}?access_token=${accessToken}`,
        method: 'POST',
        data: {
          image: imageBase64
        },
        header: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      })

      return this.parseBaiduResult(ocrResponse.data)
    } catch (error) {
      console.error('百度OCR识别失败:', error)
      throw error
    }
  }

  // 腾讯OCR识别
  async tencentOCR(imageBase64) {
    try {
      const timestamp = Math.floor(Date.now() / 1000)
      const nonce = Math.floor(Math.random() * 1000000)

      // 构建签名
      const params = {
        app_id: this.providers.tencent.appId,
        time_stamp: timestamp,
        nonce_str: nonce.toString(),
        image: imageBase64
      }

      // 这里需要实现签名算法
      const sign = this.generateTencentSign(params, this.providers.tencent.appKey)
      params.sign = sign

      const ocrResponse = await wx.request({
        url: this.providers.tencent.apiUrl,
        method: 'POST',
        data: params
      })

      return this.parseTencentResult(ocrResponse.data)
    } catch (error) {
      console.error('腾讯OCR识别失败:', error)
      throw error
    }
  }

  // 华为云OCR识别
  async huaweiOCR(imageBase64) {
    try {
      const timestamp = new Date().toISOString()
      const nonce = Math.random().toString(36).substring(2, 15)
      
      // 构建请求头
      const headers = {
        'Content-Type': 'application/json',
        'X-Sdk-Date': timestamp,
        'Authorization': this.generateHuaweiAuthHeader('POST', '/v2.0/ocr/general-text', timestamp, nonce)
      }

      // 构建请求体
      const requestBody = {
        image: imageBase64,
        url: null,
        detect_direction: true,
        quick_mode: false,
        paragraph: false,
        probability: true
      }

      const ocrResponse = await wx.request({
        url: this.providers.huawei.apiUrl,
        method: 'POST',
        data: requestBody,
        header: headers
      })

      return this.parseHuaweiResult(ocrResponse.data)
    } catch (error) {
      console.error('华为云OCR识别失败:', error)
      throw error
    }
  }

  // 解析百度OCR结果
  parseBaiduResult(result) {
    if (!result.words_result) {
      return []
    }

    return result.words_result.map((item, index) => ({
      text: item.words,
      confidence: item.probability || 0.9,
      position: {
        x: item.location?.left || 0,
        y: item.location?.top || 0,
        width: item.location?.width || 0,
        height: item.location?.height || 0
      },
      index
    }))
  }

  // 解析腾讯OCR结果
  parseTencentResult(result) {
    if (!result.data || !result.data.item_list) {
      return []
    }

    return result.data.item_list.map((item, index) => ({
      text: item.itemstring,
      confidence: item.confidence || 0.9,
      position: {
        x: item.itemcoord?.x || 0,
        y: item.itemcoord?.y || 0,
        width: item.itemcoord?.width || 0,
        height: item.itemcoord?.height || 0
      },
      index
    }))
  }

  // 解析华为云OCR结果
  parseHuaweiResult(result) {
    if (!result.result || !result.result.words_block_list) {
      return []
    }

    return result.result.words_block_list.map((item, index) => ({
      text: item.words,
      confidence: item.confidence || 0.9,
      position: {
        x: item.location?.left_top?.x || 0,
        y: item.location?.left_top?.y || 0,
        width: (item.location?.right_bottom?.x || 0) - (item.location?.left_top?.x || 0),
        height: (item.location?.right_bottom?.y || 0) - (item.location?.left_top?.y || 0)
      },
      index
    }))
  }

  // 生成腾讯API签名
  generateTencentSign(params, appKey) {
    // 按参数名排序
    const sortedKeys = Object.keys(params).sort()
    let signStr = ''
    
    sortedKeys.forEach(key => {
      signStr += `${key}=${params[key]}&`
    })
    
    signStr += `app_key=${appKey}`
    
    // 这里需要实现MD5加密
    // 实际项目中可以使用现成的MD5库
    return this.md5(signStr).toUpperCase()
  }

  // 简单的MD5实现（实际项目中建议使用成熟的MD5库）
  md5(str) {
    // 这里应该使用真实的MD5算法
    // 为了演示，返回一个简单的哈希值
    let hash = 0
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i)
      hash = ((hash << 5) - hash) + char
      hash = hash & hash // Convert to 32bit integer
    }
    return Math.abs(hash).toString(16)
  }

  // 生成华为云认证头
  generateHuaweiAuthHeader(method, uri, timestamp, nonce) {
    const accessKeyId = this.providers.huawei.accessKeyId
    const secretAccessKey = this.providers.huawei.secretAccessKey
    
    // 简化的认证头生成（实际项目中需要使用完整的AWS4签名算法）
    const signature = this.generateHuaweiSignature(method, uri, timestamp, nonce, secretAccessKey)
    
    return `AWS4-HMAC-SHA256 Credential=${accessKeyId}/${timestamp.substring(0, 8)}/cn-north-4/ocr/aws4_request, SignedHeaders=content-type;host;x-sdk-date, Signature=${signature}`
  }

  // 生成华为云签名
  generateHuaweiSignature(method, uri, timestamp, nonce, secretKey) {
    // 简化的签名生成算法
    const stringToSign = `${method}\n${uri}\n${timestamp}\n${nonce}`
    return this.hmacSha256(stringToSign, secretKey)
  }

  // HMAC-SHA256 签名
  hmacSha256(message, key) {
    // 简化的HMAC-SHA256实现
    // 实际项目中建议使用成熟的加密库
    let hash = 0
    for (let i = 0; i < message.length; i++) {
      const char = message.charCodeAt(i)
      hash = ((hash << 5) - hash) + char
      hash = hash & hash
    }
    for (let i = 0; i < key.length; i++) {
      const char = key.charCodeAt(i)
      hash = ((hash << 5) - hash) + char
      hash = hash & hash
    }
    return Math.abs(hash).toString(16)
  }

  // 识别口算题目
  extractMathProblems(ocrResults) {
    const mathProblems = []
    const mathRegex = /(\d+)\s*([+\-×÷])\s*(\d+)\s*=\s*(\d+)/

    ocrResults.forEach(item => {
      const match = item.text.match(mathRegex)
      if (match) {
        const [, num1, operator, num2, userAnswer] = match
        const problem = {
          question: `${num1} ${operator} ${num2} = ${userAnswer}`,
          num1: parseInt(num1),
          operator: operator,
          num2: parseInt(num2),
          userAnswer: parseInt(userAnswer),
          confidence: item.confidence,
          position: item.position
        }
        mathProblems.push(problem)
      }
    })

    return mathProblems
  }

  // 计算正确答案
  calculateCorrectAnswer(problem) {
    let correctAnswer
    switch (problem.operator) {
      case '+':
        correctAnswer = problem.num1 + problem.num2
        break
      case '-':
        correctAnswer = problem.num1 - problem.num2
        break
      case '×':
        correctAnswer = problem.num1 * problem.num2
        break
      case '÷':
        correctAnswer = problem.num1 / problem.num2
        break
      default:
        return null
    }
    return correctAnswer
  }

  // 批改口算题目
  gradeMathProblems(problems) {
    return problems.map(problem => {
      const correctAnswer = this.calculateCorrectAnswer(problem)
      const isCorrect = correctAnswer !== null && problem.userAnswer === correctAnswer
      
      return {
        id: problem.position.index || Math.random(),
        question: problem.question,
        userAnswer: problem.userAnswer,
        correctAnswer: correctAnswer,
        isCorrect: isCorrect,
        confidence: problem.confidence,
        position: problem.position
      }
    })
  }
}

module.exports = new OCRService()
